﻿using Inovout;
using Inovout.Descriptor;
using Inovout.Serializer;
using Inovout.Web.Mvc;
using KuaJing.Orders.Domain;
using KuaJing.Orders.Service;
using System;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Inovout.Data.Domain;
using Inovout.Data.Service;
using System.Collections.Generic;
using KuaJing.Analysis;
using System.Collections;
using System.IO.Compression;
using ICSharpCode.SharpZipLib.Zip;
using System.Text;
using KuaJing.Customs.Domain;
using KuaJing.Organization.Domain;

namespace KuaJing.Tasks.WebPages.Controllers
{
    public class OrderController : RepositoryController<Order>
    {
        public override ActionResult Index(QueryCriteria queryCriteria)
        {
            return View(QueryCriteriaBuilder
                    // .FilterFor(o => o.Code, FilterOperation.Like)
                    //.FilterFor(t => t.ExportDate, FilterOperation.GtEq)
                    //.FilterFor(t => t.ExportDate, FilterOperation.LeEq)
                    //.FilterFor(o => o.DeclarationCode, FilterOperation.Like)
                    .FilterFor(t => t.CreatedTime, FilterOperation.GtEq)
                    .FilterFor(t => t.CreatedTime, FilterOperation.LeEq)
                    //.FilterFor(t => t.CustomerName, FilterOperation.Like)
                    //.FilterFor(t => t.TradeAmount, FilterOperation.GtEq)
                    //.FilterFor(t => t.TradeAmount, FilterOperation.LeEq)
                    //.OrderDescendingFor(t => t.OrderTime)
                    .OrderDescendingFor(t => t.ReportDate)
                    .OrderDescendingFor(t => t.CustomerName)
                 .Merge(queryCriteria));
        }
        public override ActionResult Upload()
        {
            if (!GetService<IRepositoryService<Employee>>().Query().Any())
            {
                return RedirectToAction("Snyc263", "Employee", new { ReturlUrl = Url.Action("Upload", "Order") });
            }
            return base.Upload();
        }
        private IQueryable<Order> GetOrders(QueryCriteria queryCriteria)
        {
            queryCriteria = QueryCriteriaBuilder
            .FilterFor(o => o.Code, FilterOperation.Like)
                   .FilterFor(t => t.ExportDate, FilterOperation.GtEq)
                   .FilterFor(t => t.ExportDate, FilterOperation.LeEq)
                   .FilterFor(o => o.DeclarationCode, FilterOperation.Like)
                    .FilterFor(t => t.CreatedTime, FilterOperation.GtEq)
                    .FilterFor(t => t.CreatedTime, FilterOperation.LeEq)
                    .FilterFor(t => t.CustomerName, FilterOperation.Like)
                    .FilterFor(t => t.Status, FilterOperation.Eq)
                    .OrderDescendingFor(t => t.OrderTime)
                    .OrderDescendingFor(t => t.ReportDate)
                 .Merge(queryCriteria).QueryCriteria;

            var result = GetService<OrderService>().Query(queryCriteria);
            ViewData.SetQueryCriteria(queryCriteria, result);
            return result;
        }
        private IQueryable<Order> GetReportOrders(QueryCriteria queryCriteria)
        {
            queryCriteria = QueryCriteriaBuilder
                .FilterFor(o => o.Code, FilterOperation.Like)
                .FilterFor(t => t.ExportDate, FilterOperation.GtEq)
            .FilterFor(t => t.ExportDate, FilterOperation.LeEq)
           .FilterFor(o => o.DeclarationCode, FilterOperation.Like)
            .FilterFor(t => t.Status, FilterOperation.Eq)
            //.FilterFor(t => t.Customer.Source, FilterOperation.Eq)
            .OrderDescendingFor(t => t.OrderTime)
            .Merge(queryCriteria).QueryCriteria;
            var result = GetService<OrderService>().Query(queryCriteria);

            ViewData.SetQueryCriteria(queryCriteria, result);
            return result;
        }
        public ActionResult Report(QueryCriteria queryCriteria)
        {
            var orders = GetReportOrders(queryCriteria).ToArray();

            var statusCountReportData = orders.GroupBy(o => o.Status,
                  (key, orderList) =>
                  {
                      string alias = key.ToAlias();
                      return new object[] { alias, orderList.Count() };
                  });
            ViewBag.StatusCountReportData = JsonNetSerializer.Serialize(statusCountReportData, statusCountReportData.GetType());

            var statusAmountReportData = orders.GroupBy(o => o.Status,
                  (key, orderList) =>
                  {
                      string alias = key.ToAlias();
                      return new object[] { alias, orderList.Sum(o => o.TradeAmount) / 100000000 };
                  });
            ViewBag.StatusAmountReportData = JsonNetSerializer.Serialize(statusAmountReportData, statusAmountReportData.GetType());

            var providerStatusCountReportDatas = new Dictionary<string, string>();
            foreach (var provider in orders.Select(o => o.Provider).Distinct())
            {
                var providerStatusCountReportData = orders.Where(o => o.Provider == provider).GroupBy(o => o.Status,
                      (key, orderList) =>
                      {
                          string alias = key.ToAlias();
                          return new object[] { alias, orderList.Count() };
                      });
                providerStatusCountReportDatas[provider] = JsonNetSerializer.Serialize(providerStatusCountReportData, providerStatusCountReportData.GetType());
            }
            ViewBag.ProviderStatusCountReportDatas = providerStatusCountReportDatas;

            var providerStatusAmountReportDatas = new Dictionary<string, string>();
            foreach (var provider in orders.Select(o => o.Provider).Distinct())
            {
                var providerStatusAmountReportData = orders.Where(o => o.Provider == provider).GroupBy(o => o.Status,
                      (key, orderList) =>
                      {
                          string alias = key.ToAlias();
                          return new object[] { alias, orderList.Sum(o => o.TradeAmount) / 100000000 };
                      });
                providerStatusAmountReportDatas[provider] = JsonNetSerializer.Serialize(providerStatusAmountReportData, providerStatusAmountReportData.GetType());
            }
            ViewBag.ProviderStatusAmountReportDatas = providerStatusAmountReportDatas;

            IEnumerable<OrderItem> orderItems = GetService<IRepositoryService<OrderItem>>().FindAll();
            //foreach (var order in orders)
            //{
            //    orderItems.AddRange(order.Items);
            //}
            var drawbackProductCountReportData = orderItems.Where(item => item.Product.Category == ProductCategory.Drawback && (item.Order.Status == OrderStatus.Executing || item.Order.Status == OrderStatus.Executed)).GroupBy(item => item.Product,
       (key, items) =>
       {
           return new object[] { key.Name, items.Count() };
       });
            ViewBag.DrawbackProductCountReportData = JsonNetSerializer.Serialize(drawbackProductCountReportData, drawbackProductCountReportData.GetType());

            var drawbackProductAmountReportData = orderItems.Where(item => item.Product.Category == ProductCategory.Drawback && (item.Order.Status == OrderStatus.Executing || item.Order.Status == OrderStatus.Executed)).GroupBy(item => item.Product,
                (key, items) =>
                {
                    return new object[] { key.Name,
                        items.Sum(item => item.Order.TradeAmount * 0.1m * ((DrawbackOrderItem)item).Rate) / 10000 };
                });
            ViewBag.DrawbackProductAmountReportData = JsonNetSerializer.Serialize(drawbackProductAmountReportData, drawbackProductAmountReportData.GetType());


            OrderAmountAnalysis(orders);
            BIAnalysis(orders);

            return View(orders);
        }

        [HttpPost]
        public ActionResult Upload(HttpFileCollectionBase files)
        {
            try
            {
                StoreFile(f => GetService<OrderService>().Import(f));
                return RedirectToReturnUrl();
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
            //StoreFile(f => ExecuteServiceAsync<OrderService>(service => service.Import(f)));
            //return View(true);
        }

        public ActionResult Export(QueryCriteria queryCriteria)
        {
            //客户名称（简称）	省份 城市  客户类型 
            //新单 / 返单   销售人员 销售团队（有待更新）	类型 
            //类型细度1   类型细度2 类型细度3 客服 
            //订单类别    流水额（万元）	申报年月 申报时间    
            //上报时间 上报年月    出口时间 出口年月  
            //订单编号 报关单号    财务时间 财务金额（万元）	
            //产品大类 报关金额    币种 公司
            var orders = GetOrders(queryCriteria).OrderBy(o => o.CreatedTime).ToArray();
            MemoryStream stream = new MemoryStream();
            IEnumerable<string[]> cells = orders.Select(o => new string[] {
                    o.CustomerName,o.Customer==null?null:o.Customer.Province,o.Customer==null?null:o.Customer.City,null,
                    null,o.Customer==null?null:o.Customer.Sales.Person.Name,null,null,
                    null,null,null,o.Customer==null?null:o.Customer.Butler.Person.Name,
                    null,o.TradeAmount.ToString(),o.Declarations.Any()?null:o.Declarations.First().DeclarationDate.ToString("yyyy-M-d"),o.Declarations.Any()?null:o.Declarations.First().DeclarationDate.ToString("yyyy-M"),
                    o.ReportDate.HasValue?o.ReportDate.Value.ToString("yyyy-M-d"):null,o.ReportDate.HasValue?o.ReportDate.Value.ToString("yyyy-M"):null,o.ExportDate.HasValue?o.ExportDate.Value.ToString("yyyy-M-d"):null,o.ExportDate.HasValue?o.ExportDate.Value.ToString("yyyy-M"):null,
                    o.Code,o.DeclarationCode,null,null,
                    null,o.DeclarationAmount.ToString(),null,null
                });
            string header = "客户名称（简称）,省份,城市,客户类型,新单//返单,销售人员,销售团队（有待更新）,类型,类型细度1,类型细度2,类型细度3,客服,订单类别,流水额（万元）,申报年月,申报时间,上报时间,上报年月,出口时间,出口年月,订单编号,报关单号,财务时间,财务金额（万元）,产品大类,报关金额,币种,公司";
            StringBuilder sb = new StringBuilder();
            sb.AppendLine(header);
            foreach (var cell in cells)
            {
                sb.AppendLine(string.Join(",", cell));
            }
            using (ZipFile zip = ZipFile.Create(stream))
            {
                zip.BeginUpdate();

                zip.Add(new StringDataSource(sb.ToString()), "订单列表.csv");

                zip.CommitUpdate();
                stream.Position = 0;
            }
            return File(stream, "application/zip", "订单列表-" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip");
        }
        public ActionResult ExportCsv(QueryCriteria queryCriteria)
        {
            var orders = GetReportOrders(queryCriteria).ToArray();
            MemoryStream stream = new MemoryStream();
            using (ZipFile zip = ZipFile.Create(stream))
            {
                zip.BeginUpdate();

                foreach (var k in keys)
                {
                    //var amountResult = orders.KMeans(o => (double)o.TradeAmount, k, (p, os) => new object[] { Math.Round(p.Y / 10000, 2).ToString(), os.Count() });
                    var amountResult = orders.KMeans(o => (double)o.TradeAmount, k,
                    (p, os) => new
                    {
                        Key = Math.Round(p.Y / 10000, 2),
                        Report = os.GroupBy(o => o.CustomerName)
                                .Select(ogc => string.Join(",", new string[] {
                                ogc.Key, Math.Round(ogc.Sum(o => o.TradeAmount) / 10000, 2).ToString(),
                                    ogc.Count().ToString(),ogc.Max(o=>o.ExportDate).Value.ToString("yyyy-M-d") }
                                ))
                    });


                    foreach (var pointOrder in amountResult)
                    {
                        var csv = string.Join(Environment.NewLine, pointOrder.Report);
                        zip.Add(new StringDataSource("客户名称,订单金额,订单数量,最后出口日期" + Environment.NewLine + csv),
                            string.Format("订单金额聚类分析-K{0}-{1}-客户名单.csv", k.ToString(), pointOrder.Key.ToString()));

                    }
                    //var countResult = orders.GroupBy(o => o.Customer).KMeans(cos => cos.Count(), 4, (p, os) => new object[] { Math.Round(p.Y, 1).ToString(), os.Count() });
                    var countResult = orders.GroupBy(o => o.CustomerName).KMeans(cos => cos.Count(), k,
                        (p, os) => new
                        {
                            Key = Math.Round(p.Y, 1),
                            Report = os.Select(ogc => string.Join(",",
                            new string[] { ogc.Key, Math.Round(ogc.Sum(o => o.TradeAmount) / 10000, 2).ToString(), ogc.Count().ToString(),
                                ogc.Max(o=>o.ExportDate).Value.ToString("yyyy-M-d") }))
                        });

                    foreach (var pointOrder in countResult)
                    {
                        var csv = string.Join(Environment.NewLine, pointOrder.Report);
                        zip.Add(new StringDataSource("客户名称,订单金额,订单数量,最后出口蜞" + Environment.NewLine + csv),
                            string.Format("客户订单数量聚类分析-K{0}-{1}-客户名单.csv", k.ToString(), pointOrder.Key.ToString()));

                    }

                    var amountCountResult = orders.GroupBy(o => o.CustomerName).KMeans(ocs => (double)ocs.Sum(o => o.TradeAmount), cos => cos.Count(), k,
                        (p, os) =>
                        {
                            p.X = Math.Round(p.X / 10000, 2);
                            p.Y = Math.Round(p.Y, 1);
                            return new
                            {
                                Key = p,
                                Report = os.Select(ogc => string.Join(",", new string[] { ogc.Key, Math.Round(ogc.Sum(o => o.TradeAmount) / 10000, 2).ToString(), ogc.Count().ToString() }))
                            };
                        });

                    foreach (var pointOrder in amountCountResult)
                    {
                        var csv = string.Join(Environment.NewLine, pointOrder.Report);
                        zip.Add(new StringDataSource("客户名称,订单金额,订单数量" + Environment.NewLine + csv),
                            string.Format("客户订单金额数量聚类分析-K{0}-{1}-{2}-客户名单.csv", k.ToString(), pointOrder.Key.X.ToString(), pointOrder.Key.Y.ToString()));

                    }
                }
                zip.CommitUpdate();
                stream.Position = 0;
            }
            return File(stream, "application/zip", "订单相关聚类分析数据结果-" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".zip");
        }
        private void OrderAmountAnalysis(IEnumerable<Order> orders)
        {
            var orderReports = new Dictionary<string, Dictionary<string, string>>();
            foreach (var kink in new DateTimeRangeKind[] { DateTimeRangeKind.Week, DateTimeRangeKind.Month, DateTimeRangeKind.DoubleMonth, DateTimeRangeKind.Quarter })
            {
                var orderReport = orders.GroupBy(o => new DateTimeRange(o.ExportDate.HasValue ? o.ExportDate.Value : o.OrderTime.HasValue ? o.OrderTime.Value : o.ReportDate.Value, kink),
                    (key, list) => new
                    {
                        Key = key,
                        OrderCount = list.Count(),
                        OrderAmount = list.Sum(o => o.TradeAmount),
                        AvgAmount = list.Average(o => o.TradeAmount),
                        MinAmount = list.Min(o => o.TradeAmount),
                        MaxAmount = list.Max(o => o.TradeAmount),
                        CustomerCount = list.Select(o => o.CustomerName).Distinct().Count()
                    }).OrderByDescending(k => k.Key).Take(12).OrderBy(d => d.Key);
                ViewBag.OrderCountReport_Ccategories = JsonNetSerializer.Serialize(orderReport.Select(d => d.Key.ToString()));
                ViewBag.OrderCountReport_Series = JsonNetSerializer.Serialize(new object[] {
                    new { name="'订单数量'",data=orderReport.Select(o=>o.OrderCount)},
                    new { name="'客户数量'",data=orderReport.Select(o=>o.CustomerCount)}
                });

                ViewBag.OrderAmountReport_Ccategories = JsonNetSerializer.Serialize(orderReport.Select(d => d.Key.ToString()));
                ViewBag.OrderAmountReport_Series = JsonNetSerializer.Serialize(new object[] {
                    new { name="'订单金额'",data=orderReport.Select(o=>o.OrderAmount/10000)},
                    new { name="'最大金额'",data=orderReport.Select(o=>o.MaxAmount/10000)},
                    new { name="'平均金额'",data=orderReport.Select(o=>o.AvgAmount/10000)},
                    new { name="'最小金额'",data=orderReport.Select(o=>o.MinAmount/10000)}
                });
                orderReports.Add(kink.ToAlias(), new Dictionary<string, string>{
                   { "OrderAmountReport_Ccategories" , (string)ViewBag.OrderAmountReport_Ccategories },
                   { "OrderAmountReport_Series" , (string)ViewBag.OrderAmountReport_Series },
                   { "OrderCountReport_Ccategories" , (string)ViewBag.OrderCountReport_Ccategories },
                   { "OrderCountReport_Series" , (string)ViewBag.OrderCountReport_Series }
                });
            }
            ViewBag.OrderReports = orderReports;
        }
        private int[] keys = new int[] { 3, 4, 5 };

        private void BIAnalysis(IEnumerable<Order> orders)
        {
            if (!orders.Any())
            {
                ViewBag.KeysBi = Enumerable.Empty<int>();
                return;
            }
            orders = orders.Where(o => o.ReportDate.HasValue).ToArray();
            var amountResult = new Dictionary<int, string>();
            var countResult = new Dictionary<int, string>();
            var amountCountResult = new Dictionary<int, string>();
            for (int i = 0; i < keys.Length; i++)
            {
                int k = keys[i];
                Point[] cs;
                var asg = Clustering.KMeans(orders.Select(o => new Point((DateTime.Now - o.ReportDate.Value).Days, (double)o.TradeAmount)).ToArray(), k, out cs);
                amountResult.Add(k, JsonNetSerializer.Serialize(
                   cs.Select((c, index) => new object[] {
                 string.Format("单客户平均首单日期：{0}，订单金额：{1}万元",DateTime.Now.AddDays(-1*c.X).ToString("yyyy-MM-dd"),Math.Round(c.Y/10000,2).ToString()), asg.Where(s => s == index).Count() })));


                var customerOrders = orders.GroupBy(o => o.CustomerName);
                asg = Clustering.KMeans(customerOrders.Select(cos => new Point((DateTime.Now - cos.Min(o => o.ReportDate.Value)).Days, cos.Count())).ToArray(), k, out cs);


                countResult.Add(k, JsonNetSerializer.Serialize(
                     cs.Select((c, index) => new object[] {
                           string.Format("客户平均首单日期：{0}，下单数量：{1}笔",DateTime.Now.AddDays(-1*c.X).ToString("yyyy-MM-dd"), Math.Round(c.Y,1).ToString()),
                              asg.Where(s => s == index).Count() })));

                amountCountResult.Add(k, JsonNetSerializer.Serialize(
                    orders.GroupBy(o => o.CustomerName).KMeans(ocs => (double)ocs.Sum(o => o.TradeAmount), cos => cos.Count(), k,
                            (p, os) => new object[] { string.Format("{0}万元-{1}笔", Math.Round(p.X / 10000, 2), Math.Round(p.Y, 1)), os.Count() })
                    ));

            }
            ViewBag.KeysBi = keys;
            ViewBag.OrderAmountBi = amountResult;
            ViewBag.OrderCountBi = countResult;
            ViewBag.OrderAmountCountBi = amountCountResult;
        }

        public ActionResult Generate(Declaration declaration)
        {
            try
            {
                return View("Edit", GetService<OrderService>().Generate(declaration));
            }
            catch
            {
                return View("Error", (object)string.Format("没有{0}汇率", declaration.ExportDate.ToString("yyyy-M-1")));
            }
        }
        public ActionResult Relation()
        {
            try
            {
                GetService<OrderService>().Relation();
            }
            catch (Exception ex)
            {
                return Error(new Exception("没有对应当月汇率", ex));
            }
            return RedirectToReturnUrl();
        }
        class StringDataSource : IStaticDataSource
        {
            public string Str { get; set; }

            public StringDataSource(string str)
            {
                this.Str = str;
            }

            public Stream GetSource()
            {
                Stream s = new MemoryStream(Encoding.Default.GetBytes(Str));
                return s;
            }
        }


        //public class DateTimeRange : IComparable<DateTimeRange>
        //{
        //    public DateTimeRange(DateTime start, DateTimeRangeKind kind)
        //    {
        //        this.Start = start;
        //        this.Kind = kind;
        //        switch (kind)
        //        {
        //            case DateTimeRangeKind.Year:
        //                this.Start = new DateTime(start.Year, 1, 1);
        //                this.End = this.Start.AddYears(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Quarter:
        //                int month = start.Month;
        //                if (new int[] { 2, 5, 8, 11 }.Contains(month))
        //                {
        //                    month--;
        //                }
        //                else if (new int[] { 3, 6, 9, 12 }.Contains(month))
        //                {
        //                    month -= 2;
        //                }
        //                this.Start = new DateTime(start.Year, month, 1);
        //                this.End = this.Start.AddMonths(3).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Bimonthly:
        //                this.Start = new DateTime(start.Year, start.Month % 2 == 0 ? start.Month - 1 : start.Month, 1);
        //                this.End = this.Start.AddMonths(2).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Month:
        //                this.Start = new DateTime(start.Year, start.Month, 1);
        //                this.End = this.Start.AddMonths(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Week:
        //                this.Start = new DateTime(start.Year, start.Month, start.Day).AddDays(-1 * (int)start.DayOfWeek);

        //                this.End = this.Start.AddDays(7).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Day:
        //                this.Start = new DateTime(start.Year, start.Month, start.Day);
        //                this.End = this.Start.AddDays(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Hour:
        //                this.Start = new DateTime(start.Year, start.Month, start.Day, start.Hour, 0, 0);
        //                this.End = this.Start.AddHours(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Minute:
        //                this.Start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, 0);
        //                this.End = this.Start.AddMinutes(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Second:
        //                this.Start = new DateTime(start.Year, start.Month, start.Day, start.Hour, start.Minute, start.Second);
        //                this.End = this.Start.AddSeconds(1).AddMilliseconds(-1);
        //                break;
        //            case DateTimeRangeKind.Millisecond:
        //                this.Start = this.End = start;
        //                break;
        //        }
        //    }
        //    public DateTime Start { get; set; }
        //    public DateTime End { get; set; }
        //    public DateTimeRangeKind Kind { get; set; }

        //    public override bool Equals(object obj)
        //    {
        //        DateTimeRange that = obj as DateTimeRange;
        //        if (this == null)
        //        {
        //            return false;
        //        }
        //        return this.Start.Equals(that.Start) && this.End.Equals(that.End) && this.Kind.Equals(that.Kind);
        //    }
        //    public override int GetHashCode()
        //    {
        //        return this.Start.GetHashCode() ^ this.End.GetHashCode() ^ this.Kind.GetHashCode();
        //    }
        //    public override string ToString()
        //    {
        //        switch (this.Kind)
        //        {
        //            case DateTimeRangeKind.Year:
        //                return this.Start.ToString("yyyy");
        //            case DateTimeRangeKind.Bimonthly:
        //            case DateTimeRangeKind.Month:
        //            case DateTimeRangeKind.Quarter:
        //                return this.Start.ToString("yyyy-M");
        //            case DateTimeRangeKind.Week:
        //            case DateTimeRangeKind.Day:
        //                return this.Start.ToString("yyyy-M-d");
        //            case DateTimeRangeKind.Hour:
        //                return this.Start.ToString("yyyy-M-d h");
        //            case DateTimeRangeKind.Minute:
        //                return this.Start.ToString("yyyy-M-d h:m");
        //            case DateTimeRangeKind.Second:
        //                return this.Start.ToString("yyyy-M-d h:m:s");
        //            case DateTimeRangeKind.Millisecond:
        //                return this.Start.ToString();
        //        }
        //        return base.ToString();
        //    }

        //    public int CompareTo(DateTimeRange other)
        //    {
        //        return this.Start.CompareTo(other.Start);
        //    }
        //}
        //public enum DateTimeRangeKind
        //{
        //    Millisecond,
        //    Second,
        //    Minute,
        //    Hour,
        //    Day,
        //    Week,
        //    Bimonthly,
        //    Month,
        //    Quarter,
        //    Year,
        //}

    }
}